home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programmer Power Tools
/
Programmer Power Tools.iso
/
ada
/
print.me
< prev
next >
Wrap
Text File
|
1988-03-25
|
72KB
|
1,703 lines
Welcome to
A D A - T U T R
The Interactive Ada Tutor
by John J. Herro, Ph.D.
Software Innovations Technology
These are the printed course notes.
25 March 1988
Copyright 1988 John J. Herro
Software Innovations Technology
1083 Mandarin Dr. NE, Palm Bay, FL 32905-4706
(407)951-0233
You may make copies of these notes,
in printed or machine-readable form.
You may also copy the computer program.
Please see page ii for details.
Page i
TABLE OF CONTENTS
Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . ii
Registration and Licenses - What is Shareware? . . . . . . . . . . 1
Some Ada Compilers Available for the PC . . . . . . . . . . . . . 2
Before You Run ADA-TUTR on Your PC . . . . . . . . . . . . . . . . 4
Installing ADA-TUTR on Other Computers . . . . . . . . . . . . . . 5
The Ada Reserved Words . . . . . . . . . . . . . . . . . . . . . . 6
Steps for Outside Assignment 1, Preparing to Run Ada . . . . . . . 7
Listings of HELLO.ADA and ADD.ADA . . . . . . . . . . . . . . . . 8
Listing of TRITEST.ADA . . . . . . . . . . . . . . . . . . . . . . 9
Steps for Outside Assignment 2, Exercise in Enumeration Types . . 11
Listing of NEXTDATE.ADA . . . . . . . . . . . . . . . . . . . . . 12
Steps for Outside Assignment 3, Exercise in Records . . . . . . . 13
Listing of FIBTEST.ADA . . . . . . . . . . . . . . . . . . . . . . 14
Steps for Outside Assignment 4, Exercise in Recursion . . . . . . 15
Simplified Specification for TEXT_IO . . . . . . . . . . . . . . . 16
Listings of Procedure COPY and Function EXISTS . . . . . . . . . . 18
Requirements for the Program LEDIT . . . . . . . . . . . . . . . . 19
Steps for Outside Assignment 5, Writing a Simple Line Editor . . . 24
How to Test LEDIT . . . . . . . . . . . . . . . . . . . . . . . . 25
Listing of LEDIT.ANS . . . . . . . . . . . . . . . . . . . . . . . 28
Listing of TASKING.DUM . . . . . . . . . . . . . . . . . . . . . . 32
Steps for Outside Assignment 6, Exercise in Tasking . . . . . . . 33
Output from TASKING.EXE After Modification of TASKING.ADA . . . . 34
Listing of TASKING.ANS . . . . . . . . . . . . . . . . . . . . . . 35
Disclaimer of Warranty . . . . . . . . . . . . . . . . . . . . . . 36
Page ii
INTRODUCTION
ADA-TUTR, the Interactive Ada Tutor, will make you an excellent Ada
programmer in minimum time. You'll learn good Ada program design
techniques, not just Ada syntax. ADA-TUTR runs on PCs as well as
large mainframes. On PCs an Ada compiler is helpful, but not
required. The PC needs a hard disk or a 3 1/2" disk, and can have a
monochrome or a color monitor.
These printed notes aren't meant to be a complete course, or even a
summary, of Ada. They merely accompany the program ADA-TUTR, which is
a complete course. You can't "study" these printed notes alone. For
now, just read through page 3, and read pages 4 and 5 if they apply.
ADA-TUTR lets you learn at your own pace. So that you don't feel
pressured, ADA-TUTR doesn't keep track of the number of right and
wrong answers. It simply tells you whether your answers are correct,
and why. Also, there's no time limit for answering the questions or
completing the Outside Assignments.
Because I want every programmer to have a chance to learn the best
programming language, I made ADA-TUTR available very inexpensively as
Shareware. Shareware isn't the same as public domain, and ADA-TUTR
isn't free. But you may TRY it for free, and register or buy a
license only if you use it. Please see page 1 for details.
Whether or not you use ADA-TUTR and register (or buy a license),
you're encouraged to make unmodified copies and give them away.
Please put ADA-TUTR on computer bulletin boards, distribute copies at
club meetings, give them to companies, etc.! You may charge a small
fee to copy the program, provided you make it clear that the fee is
only for the copy, and doesn't pay for the Shareware. (Companies that
copy Shareware usually charge about $3 to $10 per diskette.) Bulletin
boards may carry ADA-TUTR even if they charge for access. Please
contact us for permission to include ADA-TUTR with commercial
products, such as Ada compilers (see page 3). You may use file
compression, library, and archive programs on ADA-TUTR; we won't
interpret that as "modifying" the program. You may also add your own
files. (The files included with ADA-TUTR are briefly described in
ED.DIR.) If you register, you can earn substantial money distributing
ADA-TUTR; please see page 1 for details.
Ada will become more and more important, since the Department of
Defense mandated its use in mission-critical systems, and is now
making it very hard to obtain waivers. Although learning Ada takes
real effort, you'll be able to write software that's more reliable
and easier to modify a month or a year later.
Please send me your comments and suggestions. I wish you success
using ADA-TUTR!
John J. Herro, Ph.D., Software Innovations Technology
1083 Mandarin Drive NE, Palm Bay, FL 32905-4706 (407)951-0233
Page 1
REGISTRATION AND LICENSES - WHAT IS SHAREWARE?
Shareware is a way of marketing a program. It lets you try the
program before spending any money. If you decide to use it, you send
a small payment to register your copy or buy a license. We give you
several incentives to do so, explained below. You're on your honor;
you know whether you're "using" ADA-TUTR or only "trying" it.
When registering or buying a license, please give us the serial number
from the screen that comes up when you start ADA-TUTR. We'll assign
you a new serial number. You'll have the right to use ADA-TUTR as
long as you like, and you'll get technical support for one year (it
can be renewed very inexpensively). During that time, we'll inform
you of any important updates to ADA-TUTR, and send you updated copies
for only $5 each (or FREE if you send a blank, formatted, 5 1/4" DSDD
diskette and a stamped, addressed diskette mailer). We're planning a
major update of ADA-TUTR with the next revision of the Ada language.
If you wish, you may order the current version of ADA-TUTR (with your
serial number) when you register or buy a license. If you need or
want an invoice (or an order form), please print the file INVOICE.TXT.
We sell anywhere in the Free World; outside the U.S., please remit in
U.S. funds and contact us about extra postal charges on diskettes.
INDIVIDUALS: Register your copy for only $25. When you get your new
serial number, run CHANGESN to put it into the program. Then give
copies to individuals, companies, schools, clubs, computer bulletin
boards, etc. We'll send you a commission of $5 for each individual
who registers from one of your copies, and 10 PERCENT for each license
sold from one of your copies! As you can see from the next paragraph,
you can earn up to $240 per license sold! Commissions are paid
quarterly. If you like, print the file AD.TXT and use copies as an
advertisement. You can renew technical support for only $10 a year.
Even if you don't renew, you'll continue to receive commissions.
COMPANIES, SCHOOLS, OTHER ORGANIZATIONS: Register each individual
user, as described above, or buy a Multi-User License as follows:
Number of Users: Price of License:
Up to 100 only $450
Up to 500 only $725
Up to 2000 only $950
Unlimited only $2400
This gives the specified number of people the right to use ADA-TUTR as
long as you like, on all your computers, from PCs to large mainframes.
Page 5 shows how to install ADA-TUTR on non-PC computers. Commissions
are NOT paid to Multi-User Licensees. Renewal of technical support is
only 10% of the price of the license per year. With Shareware, you
never have to worry about software piracy, because your people are
ENCOURAGED to copy and distribute the program!
Software Innovations Technology
1083 Mandarin Dr. NE, Palm Bay, FL 32905-4706
(407)951-0233
Page 2
SOME ADA COMPILERS AVAILABLE FOR THE PC
Here's a brief list of Ada compilers available for the PC and
compatibles. For this course, an Ada compiler is helpful, but not
required. There are six Outside Assignments; most of them ask you to
write and compile a short Ada program. If you don't have access to an
Ada compiler, just skip the Outside Assignments.
All of the compilers in this list run on a PC/XT or larger machine,
except as noted.
We have no financial interest in any company mentioned here. If you
know of an Ada compiler for the PC that you think should be on this
list, please contact us.
All of the company names and all of the compiler names except Augusta
are trademarks of the respective companies.
1. At the low end of the scale is Augusta. This compiler is in the
public domain, and can be found on many computer bulletin boards.
It's a very small subset of Ada with no packages. It translates
Ada to a P-code, and then interprets the P-code. The spelling of
the Ada reserved word "elsif" is non-standard; Augusta uses
"elseif." The compiler requires Turbo Pascal (tm Borland
International).
2. ADA/Ed-C is a full Ada "translator" available from NYUADA Project,
New York University, 251 Mercer St., New York, NY 10012, for $95.
It translates Ada to an intermediate code and then interprets. On
a PC/XT, programs larger than a few hundred lines run out of
memory, but on a PC/AT, the translator passes all the tests of the
validation suite.
3. Janus/Ada is now validated, and is sold by R & R Software, Box
1512, Madison, WI 53701, starting at $99.95. It compiles to
native code, and doesn't need an interpreter.
4. Artek Ada is sold for $495 by Artek Corp., 835 E. 25th Ave.,
Eugene, OR 97405. It's nearly a full Ada, and can produce native
code. It includes a source code debugger, the textbook by S. J.
Young mentioned in ADA-TUTR, and a copy of the LRM. As of this
writing (March, 1988), they're working on a validated version,
which will be sold by a well-known company whose name they haven't
yet revealed.
5. AdaVantage is sold by Meridian Software, Inc., 23141 Verdugo Dr.,
Suite 105, Laguna Hills, CA 92653, starting at $795. It's
validated and produces native code. A "starter" version which
compiles small programs is available for $95.
-- continued --
Page 3
6. At the high end of the scale is Alsys Ada, sold by Alsys, Inc.,
1432 Main St., Waltham, MA 02154, for $3300. It's a validated
Ada that runs only on a PC/AT, but can produce native code for the
PC/XT. The price includes an extra memory board for the AT.
COMPILER COMPANIES:
A commercial version of ADA-TUTR is available, without the Shareware
notices and without this list of Ada compilers. You can greatly
increase the sales appeal and value of your Ada compiler by including
the commercial version of ADA-TUTR. Contact us for terms.
DO YOU NEED A SCREEN EDITOR / WORD PROCESSOR?
The Outside Assignments will be much easier if you have a good screen
editor. We've looked at many, and found PC-Write (tm), a Shareware
program by Quicksoft (tm) of Seattle, WA to be the best screen editor
as well as word processor. There's lots of on-line help, and the
50000-word spelling checker can be turned on for editing letters and
documents, and off for editing source code. We liked the idea of
having to learn only ONE program for both kinds of editing. Unlike
ADA-TUTR, PC-Write runs only on PCs and compatibles, not on
mainframes, etc.
We have no connection with Quicksoft, except for being a registered
user of PC-Write. However, we'll be happy to send you a copy of the
latest version of that excellent program, if you send us two blank,
formatted, 5 1/4" DSDD diskettes and a stamped, addressed diskette
mailer, OR $10. The $10 fee only covers our expenses; you must
register your copy of PC-Write with Quicksoft if you use it after a
free trial. We're sorry, but we're not allowed to send copies of
PC-Write outside North America.
If you do use PC-Write to edit Ada programs, you may find the file
ED.ADA, included with ADA-TUTR, to be helpful. It allows typing many
Ada reserved words with a single keystroke. For example, you can type
"procedure" by striking Alt-P. See the file ED.ADA for more details.
PC-Write will automatically invoke ED.ADA whenever you edit a file
with the extension .ADA.
Software Innovations Technology
1083 Mandarin Dr. NE, Palm Bay, FL 32905-4706
(407)951-0233
Page 4
BEFORE YOU RUN ADA-TUTR ON YOUR PC
Give the command TYPE READ.ME on your PC. If one word appears
brighter than the rest, you can skip this page. However, if your
screen shows strange characters like "[1m", you need to read this.
ADA-TUTR uses ANSI (American National Standards Institute) escape
sequences for highlighting, reverse video, and cursor positioning.
Therefore, the device driver ANSI.SYS must be installed before
ADA-TUTR will work correctly. To install ANSI.SYS, do the following:
1. If there's a file CONFIG.SYS in the root directory of the disk
from which you boot, type it and look for a line saying
"DEVICE=ANSI.SYS" (without the quotes), in either upper or lower
case. If that line is not present, add it to CONFIG.SYS anywhere
in the file, using an ordinary text editor or word processor in
the non-document mode. If there's no CONFIG.SYS file, create one
containing the single line "DEVICE=ANSI.SYS" (without the quotes).
2. If there's no file ANSI.SYS in your root directory, copy ANSI.SYS
from from your system distribution diskette to the root directory
of the disk from which you boot.
3. Reboot the computer. ADA-TUTR should then work correctly.
Page 5
INSTALLING ADA-TUTR ON OTHER COMPUTERS
Because source code is included with ADA-TUTR, you can install
ADA-TUTR on almost any computer that has an Ada compiler - from
portable units to large mainframes. ADA-TUTR is written in Ada (of
course!), and Ada programs tend to be very portable.
The screen should have at least 24 rows of 80 characters each, and
should support the ANSI escape sequences for highlighting, reverse
video, and cursor positioning. Almost all computers qualify.
You'll need a way to send files from your PC to the other computer.
Files are usually sent to large mainframes with the program KERMIT,
which is in the public domain. One version of KERMIT runs on the PC,
another on the mainframe. The two communicate with each other.
Send all the files that come with ADA-TUTR, except ADA-TUTR.DAT and
the files ending in .EXE. Don't try to send those files, because
they're not text files. Then, create ADA-TUTR.DAT on the other
computer as follows: Run DAT2TXT on the PC to translate the file
ADA-TUTR.DAT to a text file TUTOR.TXT. Send TUTOR.TXT to the other
computer. Then compile and run TXT2DAT.ADA on the other computer to
translate TUTOR.TXT to ADA-TUTR.DAT on that machine. On a few
systems, our file names are illegal and you'll have to change the file
names following "NAME =>" inside TXT2DAT.ADA and ADA-TUTR.ADA.
The next step is to compile, on the other computer, NON-PC.ADA and
then ADA-TUTR.ADA. Then link, giving the name of the main program,
which is ADA_TUTR with an underline. Some compilers call the linking
step "binding." This will produce an executable file, which will be
called ADA_TUTR.EXE (with an underline) on most systems. You should
rename ADA_TUTR.EXE as ADA-TUTR.EXE. Finally, run ADA-TUTR.
On some systems, you may have to strike ENTER (or RETURN or NEW-LINE)
after each response, even though the program says "You need not hit
ENTER." Also note that some of the text refers to commands that are
meant for a PC, such as "COPY TRITYPE.DUM TRITYPE.ADA". These
commands may have to be varied slightly to work on your system.
So far as we know, the file NON-PC.ADA will work with any standard Ada
compiler. However, if you're using VAX Ada (tm, Digital Equipment
Corp.), the file VAX.ADA will work work even better. Compile it
instead of NON-PC.ADA. If you compile NON-PC.ADA with VAX Ada, you'll
have to hit RETURN after each response. If you compile VAX.ADA
instead, you won't have to hit RETURN, because VAX.ADA makes use of
the System Service routines.
When you compile ADA-TUTR.ADA, if you get error messages saying that
QGET and CON_IO aren't found in the library, you probably forgot to
compile NON-PC.ADA or VAX.ADA first.
We'll be happy to help you install ADA-TUTR and get it running, even
if you haven't registered or bought a license. We want you to try
ADA-TUTR before paying for it.
Page 6
THE ADA RESERVED WORDS
The 63 reserved words are listed in the Language Reference Manual in
section 2.9, and are repeated here for convenience.
abort declare generic of select
abs delay goto or separate
accept delta others subtype
access digits if out
all do in task
and is package terminate
array pragma then
at else private type
elsif limited procedure
end loop
begin entry raise use
body exception range
exit mod record when
rem while
new renames with
case for not return
constant function null reverse xor
Page 7
STEPS FOR OUTSIDE ASSIGNMENT 1, PREPARING TO RUN ADA
For the first Outside Assignment, learn enough about your Ada compiler
to compile and run the two simple programs HELLO.ADA and ADD.ADA.
Obviously, you have to do this before you can do the remaining Outside
Assignments.
1. Compile HELLO.ADA. On most systems, after the Ada compiler is
installed and your library is created, this only involves typing
ADA HELLO or ADA HELLO.ADA. On some systems, the compiler is invoked
from a menu or "APSE" (Ada Programming Support Environment), and you
must first specify HELLO as the name of the "working file."
2. Link, giving the name of the main program, HELLO. This usually
involves typing LINK HELLO or BIND HELLO, perhaps with some options.
On one system, the command is BAMP HELLO, for Build Ada Main Program!
3. Run the program. If your Ada compiler produces native code on a
PC, it created a file HELLO.EXE, and this step simply involves typing
HELLO. On other systems, the command RUN HELLO is appropriate. On
some systems, you have to invoke an interpreter to run the program.
4. Now compile, link, and run ADD.ADA.
If your compiler implements a subset of Ada, you may have to modify
the programs in this and later Outside Assignments to get them to
compile. Some compilers don't allow "separate" compilation (used in
later assignments), and you'll have to include the "separate"
subprograms inside the main program and compile them as one. Some
compilers don't allow generic instantiation, and have another way of
displaying integers. In that case, you'll have to modify ADD.ADA. If
you're using a validated compiler, you shouldn't have to worry about
any of this, because all of the Outside Assignments are written in
standard Ada.
Page 8
HELLO.ADA
---------
with TEXT_IO; use TEXT_IO;
procedure HELLO is
begin
PUT_LINE("Hello!");
end HELLO;
ADD.ADA
-------
with TEXT_IO; use TEXT_IO;
procedure ADD is
package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
begin
PUT(2 + 2);
NEW_LINE;
end ADD;
Page 9
TRITEST.ADA
-----------
with TEXT_IO; use TEXT_IO;
procedure TRITEST is
PASSED : BOOLEAN := TRUE;
type TRIANGLE is (EQUILATERAL, ISOSCELES, SCALENE, NOT_A_TRIANGLE);
function TRITYPE(LEN1, LEN2, LEN3 : in INTEGER) return TRIANGLE
is separate;
procedure COMPARE(A, B, C: in INTEGER; RIGHT_ANSWER : in TRIANGLE)
is separate;
begin
COMPARE( 3, 4, 5, SCALENE);
COMPARE( 6, 3, 4, SCALENE);
COMPARE( 4, 3, 6, SCALENE);
COMPARE( 3, 3, 3, EQUILATERAL);
COMPARE( 3, 3, 4, ISOSCELES);
COMPARE( 3, 4, 3, ISOSCELES);
COMPARE( 4, 3, 3, ISOSCELES);
COMPARE( 7, 7, 4, ISOSCELES);
COMPARE( 7, 4, 7, ISOSCELES);
COMPARE( 4, 7, 7, ISOSCELES);
COMPARE( 1, 1, 1, EQUILATERAL);
COMPARE( 0, 4, 4, NOT_A_TRIANGLE);
COMPARE( 4, 0, 4, NOT_A_TRIANGLE);
COMPARE( 4, 4, 0, NOT_A_TRIANGLE);
COMPARE( 0, 4, 3, NOT_A_TRIANGLE);
COMPARE( 3, 0, 4, NOT_A_TRIANGLE);
COMPARE( 4, 3, 0, NOT_A_TRIANGLE);
COMPARE(-1, 4, 4, NOT_A_TRIANGLE);
COMPARE( 4, -1, 4, NOT_A_TRIANGLE);
COMPARE( 4, 4, -1, NOT_A_TRIANGLE);
COMPARE(-1, 4, 3, NOT_A_TRIANGLE);
COMPARE( 3, -1, 4, NOT_A_TRIANGLE);
COMPARE( 4, 3, -1, NOT_A_TRIANGLE);
COMPARE( 2, 4, 6, NOT_A_TRIANGLE);
COMPARE( 1, 3, 2, NOT_A_TRIANGLE);
COMPARE( 3, 1, 2, NOT_A_TRIANGLE);
COMPARE( 1, 2, 4, NOT_A_TRIANGLE);
COMPARE( 1, 4, 2, NOT_A_TRIANGLE);
COMPARE( 4, 1, 2, NOT_A_TRIANGLE);
COMPARE( 0, 0, 0, NOT_A_TRIANGLE);
COMPARE( 0, 0, 4, NOT_A_TRIANGLE);
COMPARE( 0, 4, 0, NOT_A_TRIANGLE);
COMPARE( 4, 0, 0, NOT_A_TRIANGLE);
COMPARE( 3, 3, 7, NOT_A_TRIANGLE);
COMPARE( 3, 7, 3, NOT_A_TRIANGLE);
COMPARE( 6, 3, 3, NOT_A_TRIANGLE);
COMPARE(-3, -4, -5, NOT_A_TRIANGLE);
if PASSED then
PUT_LINE("Congratulations, you completed the assignment!");
end if;
end TRITEST;
-- continued --
Page 10
separate(TRITEST)
procedure COMPARE(A, B, C: in INTEGER; RIGHT_ANSWER : in TRIANGLE) is
package INT_IO is new INTEGER_IO(INTEGER); use INT_IO;
package TRI_IO is new ENUMERATION_IO(TRIANGLE); use TRI_IO;
MY_ANSWER : TRIANGLE := TRITYPE(A, B, C);
begin
if MY_ANSWER /= RIGHT_ANSWER then
PUT("Sides:");
PUT(A, WIDTH => 3);
PUT(B, WIDTH => 3);
PUT(C, WIDTH => 3);
PUT(" My answer: ");
PUT(MY_ANSWER, WIDTH => 14);
PUT(" Right answer: ");
PUT(RIGHT_ANSWER);
NEW_LINE;
PASSED := FALSE;
end if;
end COMPARE;
Page 11
STEPS FOR OUTSIDE ASSIGNMENT 2, EXERCISE IN ENUMERATION TYPES
1. Compile the test driver TRITEST.ADA. Also, make a copy of the
dummy solution by typing COPY TRITYPE.DUM TRITYPE.ADA. You need
do this step only once.
2. Edit TRITYPE.ADA to become your real solution. You can skip this
step the first time through, to see error messages from the test
driver.
3. Compile your solution TRITYPE.ADA. If there are compiler errors,
go back to step 2.
4. Link with the name of the main program TRITEST. Then execute. If
the test driver prints error messages, go back to step 2.
5. When the message "Congratulations, you completed the assignment!"
is printed, you'll have a chance to compare your solution with
ours.
Page 12
NEXTDATE.ADA
------------
with TEXT_IO; use TEXT_IO;
procedure NEXTDATE is
type MONTH_TYPE is
(JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC);
subtype DAY_SUBTYPE is INTEGER range 1 .. 31;
type DATE is
record
DAY : DAY_SUBTYPE;
MONTH : MONTH_TYPE;
YEAR : POSITIVE;
end record;
PASSED : BOOLEAN := TRUE;
function TOMORROW(TODAY : in DATE) return DATE is separate;
procedure DISPLAY (S : in STRING; D : in DATE) is
package INT_IO is new INTEGER_IO(INTEGER); use INT_IO;
package MON_IO is new ENUMERATION_IO(MONTH_TYPE); use MON_IO;
begin
PUT(S);
PUT(D.DAY, WIDTH => 3); PUT(" ");
PUT(D.MONTH);
PUT(D.YEAR, WIDTH => 5); NEW_LINE;
end DISPLAY;
procedure COMPARE(TODAY, RIGHT_ANSWER : in DATE) is
MY_ANSWER : DATE := TOMORROW(TODAY);
begin
if MY_ANSWER /= RIGHT_ANSWER then
DISPLAY("Today: ", TODAY);
DISPLAY("My answer: ", MY_ANSWER);
display("Right answer:", RIGHT_ANSWER);
NEW_LINE;
PASSED := FALSE;
end if;
end COMPARE;
begin
COMPARE((12,DEC,1815), (13,DEC,1815)); -- ordinary date
COMPARE(( 3,FEB,1986), ( 4,FEB,1986)); -- ordinary date in Feb.
COMPARE((30,JUN,1981), ( 1,JUL,1981)); -- last day of 30-day month
COMPARE((30,SEP,3999), ( 1,OCT,3999)); -- last day of 30-day month
COMPARE((31,MAR,1876), ( 1,APR,1876)); -- last day of 31-day month
COMPARE((31,AUG,1984), ( 1,SEP,1984)); -- last day of 31-day month
COMPARE((31,DEC,1966), ( 1,JAN,1967)); -- last day of year
COMPARE((28,FEB,1980), (29,FEB,1980)); -- leap year
COMPARE((28,FEB,1600), (29,FEB,1600)); -- century leap year
COMPARE((28,FEB,2100), ( 1,MAR,2100)); -- century non-leap year
COMPARE((28,FEB,1982), ( 1,MAR,1982)); -- non-leap year
COMPARE((29,FEB,1980), ( 1,MAR,1980)); -- leap day in leap year
if PASSED then
PUT_LINE("Congratulations, you completed the assignment!");
end if;
end NEXTDATE;
Page 13
STEPS FOR OUTSIDE ASSIGNMENT 3, EXERCISE IN RECORDS
1. Compile the test driver NEXTDATE.ADA. Also, make a copy of the
dummy solution by typing COPY TOMORROW.DUM TOMORROW.ADA. You need
do this step only once.
2. Edit TOMORROW.ADA to become your real solution. You can skip this
step the first time through, to see error messages from the test
driver.
3. Compile TOMORROW.ADA. If there are compiler errors, go back to
step 2.
4. Link with the name of the main program NEXTDATE. Then execute.
If the test driver prints error messages, go back to step 2.
5. When the message "Congratulations, you completed the assignment!"
is printed, you'll have a chance to compare your solution with
ours.
Page 14
FIBTEST.ADA
-----------
with TEXT_IO; use TEXT_IO;
procedure FIBTEST is
PASSED : BOOLEAN := TRUE;
function FIBONACCI(N : in POSITIVE)return POSITIVE is separate;
procedure COMPARE (N : in POSITIVE; RIGHT_ANSWER : in POSITIVE) is
package INT_IO is new INTEGER_IO(INTEGER); use INT_IO;
MY_ANSWER : POSITIVE := FIBONACCI(N);
begin
if MY_ANSWER /= RIGHT_ANSWER then
PUT("N:"); PUT(N);
PUT(" My answer:"); PUT(MY_ANSWER);
PUT(" Right answer:"); PUT(RIGHT_ANSWER);
NEW_LINE;
PASSED := FALSE;
end if;
end COMPARE;
begin
COMPARE(1,1);
COMPARE(2,1);
COMPARE(3,2);
COMPARE(4,3);
COMPARE(5,5);
COMPARE(6,8);
COMPARE(7,13);
COMPARE(10,55);
COMPARE(15,610);
COMPARE(20,6765);
if PASSED then
PUT_LINE("Congratulations, you completed the assignment!");
end if;
end FIBTEST;
Page 15
STEPS FOR OUTSIDE ASSIGNMENT 4, EXERCISE IN RECURSION
1. Compile the test driver FIBTEST.ADA. Also, make a copy of the
dummy solution by typing COPY FIB.DUM FIB.ADA. You need do this
step only once.
2. Edit FIB.ADA to become your real solution. You can skip this step
the first time through, to see error messages from the test
driver.
3. Compile FIB.ADA. If there are compiler errors, go back to step 2.
4. Link with the name of the main program FIBTEST. Then execute. If
the test driver prints error messages, go back to step 2.
5. When the message "Congratulations, you completed the assignment!"
is printed, you'll have a chance to compare your solution with
ours.
Page 16
SIMPLIFIED SPECIFICATION FOR TEXT_IO
------------------------------------
package TEXT_IO is
type FILE_TYPE is limited private;
type FILE_MODE is (IN_FILE, OUT_FILE);
type COUNT is ... (a user-defined type similar to INTEGER);
STATUS_ERROR, MODE_ERROR, NAME_ERROR, END_ERROR : exception;
procedure CREATE (FILE : in out FILE_TYPE;
MODE : in FILE_MODE := OUT_FILE;
NAME : in STRING);
procedure OPEN (FILE : in out FILE_TYPE;
MODE : in FILE_MODE;
NAME : in STRING);
procedure CLOSE (FILE : in out FILE_TYPE);
procedure DELETE (FILE : in out FILE_TYPE);
procedure NEW_LINE (SPACING : in COUNT := 1);
procedure NEW_LINE (FILE : in FILE_TYPE;
SPACING : in COUNT := 1);
procedure SKIP_LINE (SPACING : in COUNT := 1);
procedure SKIP_LINE (FILE : in FILE_TYPE;
SPACING : in COUNT := 1);
function END_OF_FILE (FILE : in FILE_TYPE) return BOOLEAN;
procedure PUT (ITEM : in CHARACTER);
procedure PUT (FILE : in FILE_TYPE; ITEM : in CHARACTER);
procedure GET (ITEM : out CHARACTER);
procedure GET (FILE : in FILE_TYPE; ITEM : out CHARACTER);
procedure PUT (ITEM : in STRING);
procedure PUT (FILE : in FILE_TYPE; ITEM : in STRING);
procedure PUT_LINE (ITEM : in STRING);
procedure PUT_LINE (FILE : in FILE_TYPE; ITEM : in STRING);
procedure GET_LINE (ITEM : out STRING; LAST : out NATURAL);
procedure GET_LINE (FILE : in FILE_TYPE;
ITEM : out STRING;
LAST : out NATURAL);
generic
type NUM is range <>;
package INTEGER_IO is
procedure GET (ITEM : out NUM);
procedure GET (FILE : in FILE_TYPE; ITEM : out NUM);
procedure PUT (ITEM : in NUM;
WIDTH : in INTEGER := ...;
BASE : in INTEGER := 10);
procedure PUT (FILE : in FILE_TYPE;
ITEM : in NUM;
WIDTH : in INTEGER := ...;
BASE : in INTEGER := 10);
end INTEGER_IO;
-- continued --
Page 17
generic
type NUM is digits <>;
package FLOAT_IO is
procedure GET (ITEM : out NUM);
procedure GET (FILE : in FILE_TYPE; ITEM : out NUM);
procedure PUT (ITEM : in NUM;
FORE : in INTEGER := 2;
AFT : in INTEGER := ...;
EXP : in INTEGER := 3);
procedure PUT (FILE : in FILE_TYPE;
ITEM : in NUM;
FORE : in INTEGER := 2;
AFT : in INTEGER := ...;
EXP : in INTEGER := 3);
end FLOAT_IO;
generic
type ENUM is (<>);
package ENUMERATION_IO is
procedure GET (ITEM : out ENUM);
procedure GET (FILE : in FILE_TYPE; ITEM : out ENUM);
procedure PUT (ITEM : in ENUM; WIDTH : in INTEGER := 0);
procedure PUT (FILE : in FILE_TYPE;
ITEM : in ENUM; WIDTH : in INTEGER := 0);
end ENUMERATION_IO;
private
type FILE_TYPE is ... (implementation dependent);
end TEXT_IO;
Page 18
Program to copy a simple text file:
-----------------------------------
with TEXT_IO; use TEXT_IO;
procedure COPY is
F1, F2 : FILE_TYPE;
S : STRING(1 .. 80);
LEN : INTEGER;
begin
PUT("Input file: "); GET_LINE(S, LEN);
OPEN(FILE => F1, MODE => IN_FILE, NAME => S(1 .. LEN));
PUT("Output file: "); GET_LINE(S, LEN);
CREATE(FILE => F2, MODE => OUT_FILE, NAME => S(1 .. LEN));
while not END_OF_FILE(F1) loop
GET_LINE(F1, S, LEN);
PUT_LINE(F2, S(1 .. LEN));
end loop;
CLOSE(F1);
CLOSE(F2);
end COPY;
Function to test if a text file exists:
---------------------------------------
with TEXT_IO; use TEXT_IO;
function EXISTS(FILE_NAME : in STRING) return BOOLEAN is
F : FILE_TYPE;
ANSWER : BOOLEAN := TRUE;
begin
begin
OPEN(F, IN_FILE, S);
CLOSE(F);
exception
when NAME_ERROR => ANSWER := FALSE;
end;
return ANSWER;
end EXISTS;
Page 19
REQUIREMENTS FOR THE PROGRAM LEDIT
This assignment will give you practice in writing a program of greater
complexity than the previous programs you've written. Imagine that
your screen editor is unavailable to a particular user, perhaps
because he's dialing your computer from a remote location, and your
screen editor writes directly to the screen. You want to write a very
simple line editor, LEDIT, that could be used in such circumstances.
While your computer already has a line editor called EDLIN, it's
difficult to learn to use. LEDIT will take almost no effort to learn.
The only commands are LIST and EXIT. The line editor edits by means
of line numbers, similar to the Basic language.
The user begins each line of text that he types with a line number
from 1 to 29999. Line numbers must be integers. The upper limit
29999 was chosen so that the simple type INTEGER could be used - in
any implementation of Ada. Regardless of the order in which lines
are typed, LEDIT maintains a linked list of lines in order by number.
Also, line numbers may be preceded by any number of spaces. For
example, if the user types
40 -- This is a comment.
20 begin
10 with TEXT_IO; use TEXT_IO;
30 end ADD;
and then types LIST, the editor will type
10 with TEXT_IO; use TEXT_IO;
20 begin
30 end ADD;
40 -- This is a comment.
To INSERT lines, the user merely types lines with intermediate line
numbers. For example, if he types
15 procedure HELLO is
and then types LIST, LEDIT will type
10 with TEXT_IO; use TEXT_IO;
15 procedure HELLO is
20 begin
30 end ADD;
40 -- This is a comment.
To REPLACE an existing line, the user merely types a line with the
same line number as the line to be replaced. For example, if he typed
15 procedure ADD is
LIST
-- continued --
Page 20
LEDIT would then show
10 with TEXT_IO; use TEXT_IO;
15 procedure ADD is
20 begin
30 end ADD;
40 -- This is a comment.
Finally, to DELETE a line, the user merely types the number of the
line to be deleted, followed immediately by a carriage return. Typing
40
LIST
would then produce
10 with TEXT_IO; use TEXT_IO;
15 procedure ADD is
20 begin
30 end ADD;
Thus the user can INSERT, REPLACE, and DELETE lines, all by line
numbers, without learning any commands. Note that in this simple
editor there is no "cursor" or "current line."
The space is not required after the line number. These two lines have
exactly the same effect:
20 begin
20begin
Of course, if the text of the line begins with a digit, a space will
be required to separate it from the line number. In any event, LEDIT
always leaves one blank space after the line number when LISTing, for
readability. It always allows exactly five spaces for the line number
itself.
However, any EXTRA spaces typed after the line number are significant.
The three lines below each contain three EXTRA spaces after the line
number, for a total of four spaces.
24 PUT(2 + 2);
26 NEW_LINE;
18 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
They have the effect of indenting the text three spaces. LIST now
shows
-- continued --
Page 21
10 with TEXT_IO; use TEXT_IO;
15 procedure ADD is
18 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
20 begin
24 PUT(2 + 2);
26 NEW_LINE;
30 end ADD;
Although typing a line number followed immediately by a carriage
return deletes a line (if there is a line by that number), typing a
line number followed by a single space causes an empty line to be
introduced into the file. For example, typing 12 followed by a single
space and a carriage return would then cause LIST to type
10 with TEXT_IO; use TEXT_IO;
12
15 procedure ADD is
18 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
20 begin
24 PUT(2 + 2);
26 NEW_LINE;
30 end ADD;
When LEDIT is run, it prompts for the names of the input and output
files. If the input file exists, LEDIT prints "File found" and reads
the file into its linked list, assigning line numbers starting with 10
and incrementing by 10. If the file does not exist, LEDIT prints
"File not found," and the linked list is initially empty. In any
event, LEDIT creates an output file. When the EXIT command is given,
LEDIT writes the contents of the linked list to the output file. In
doing so, LEDIT removes the line numbers and the first blank after
each line number.
In the example above, let us assume that the user typed ADD.ADA for an
output file name. When he types EXIT, the new file ADD.ADA created by
LEDIT will contain:
with TEXT_IO; use TEXT_IO;
procedure ADD is
package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
begin
PUT(2 + 2);
NEW_LINE;
end ADD;
(Note that the file contains one empty line.) Your program is not
allowed to add any trailing blanks of its own in the output file. If
the user again runs LEDIT and specifies ADD.ADA as an input file, the
editor will type "File found" and read the file. LIST will show
-- continued --
Page 22
10 with TEXT_IO; use TEXT_IO;
20
30 procedure ADD is
40 package MY_INT_IO is new INTEGER_IO(INTEGER); use MY_INT_IO;
50 begin
60 PUT(2 + 2);
70 NEW_LINE;
80 end ADD;
When he EXITs, the new file will contain modified text. The old file
will still be present until it is deleted.
The two commands LIST and EXIT must be accepted in either upper or
lower case, but for simplicity, they need not be accepted in a mixture
of cases. They may be preceded by any number of spaces. The LIST
command must be accepted in any of the following forms:
LIST (Lists all lines, if any, otherwise does nothing.)
list 30 (Lists line 30, if it exists.)
list 25 - 35 (Lists all lines between 25 and 35 inclusive, if any.)
LIST - 35 (Lists all lines numbered 35 or less, if any.)
list 25 - (Lists all lines numbered 25 or more, if any.)
Furthermore, all spaces are optional in the LIST command provided that
LIST is written solid, so that LIST25-35 is equivalent to the third
example above. Any other forms of LIST should be flagged as an error.
In particular, all of these should give error messages:
LIST -
list 2A
LIST 30 - 50 -
list 30 - -50
list 30-A
LIST XYZ
The EXIT command must stand alone; unlike LIST, EXIT is never followed
by anything. Except for the LIST and EXIT commands, every line typed
must begin with a number between 1 and 29999. (Of course, the user
should be able to type just a carriage return with no effect.) LEDIT
should check that line numbers are in range when adding or replacing
lines. The LIST command need not check the range of the line numbers,
because it should be impossible to create lines with improper numbers.
Your program need not handle input files so long that 29999 would be
exceeded when it assigns line numbers starting at 10 with an increment
of 10.
Your LEDIT must prompt for input and output file names at the start,
and it may print a prompt for each line that the user types. You may
assume some maximum length for an input line (e.g., 80), and assume
that no file will have lines longer than the maximum.
-- continued --
Page 23
For simplicity, there's no way to edit a line except by retyping it.
Also, there's no way to copy or move a line or a block of lines, and
no way to delete a block of lines except one line at a time. There's
no RENUMBER command. The user can renumber the entire file starting
at 10 with an increment of 10 by EXITing and then rerunning LEDIT.
There's no AUTO command to make the editor type the line numbers
automatically while text is being typed from the keyboard, and there's
no means of recovering from a system crash that occurred during an
edit. Additionally, there's no way to search for a string, or replace
one string with another. These features would all be desirable, but
we feel that Outside Assignment 5 is challenging as it stands.
You're encouraged to make use of Ada's separate compilation feature,
so that you don't have to recompile the entire program when developing
a module.
As a point of reference, our solution to this assignment consists of
about 180 lines of code on four pages. If you have any questions
about what LEDIT should do, you can compile and run our solution,
which is in LEDIT.ANS.
The following declarations are offered by way of suggestion only, and
you should use them only if you feel comfortable with them:
MAX_LENGTH : constant INTEGER := 80;
type TEXT is
record
LEN : INTEGER range 0 .. MAX_LENGTH;
VAL : STRING(1 .. MAX_LENGTH);
end record;
type LINK;
type P is access LINK;
type LINK is
record
NUM : POSITIVE;
LINE : TEXT;
NEXT : P;
end record;
function STR(T : in TEXT) return STRING;
In our solution, we used type TEXT as above. However, we didn't write
a TEXT_HANDLER package, because it didn't seem to be needed. We used
a one-page main program with several "separate" subprograms.
Page 24
STEPS FOR OUTSIDE ASSIGNMENT 5, WRITING A SIMPLE LINE EDITOR
1. Carefully read the requirements starting on page 19 of these
notes. Take your time.
2. Write the Ada code, compile, and link. Call the main program
LEDIT. If you have any questions about what LEDIT should do, you
can compile and run our solution, which is in LEDIT.ANS.
3. Refer to pages 25-27 of these notes for instructions on testing
your line editor. If any tests are failed, go back to step 2.
4. When all the tests are passed, you've completed the assignment and
will have a chance to compare your solution with ours.
Page 25
HOW TO TEST LEDIT
1. Run LEDIT and give the name of an input file that doesn't exist.
LEDIT should say "File not found." Give another name of a file that
doesn't exist for an output file.
2. Type "LIST" (without the quotes) to make sure that LEDIT can
handle the LIST command when no text has been entered.
3. Type "EXI". The program should NOT exit. If it exits, it's
probably because the "T" was left in the input buffer from the LIST
command. Your program is checking the first four characters of the
input buffer without checking the length of the typed command.
4. Type "ABC". The program should print a message about an illegal
or unrecognized command, or syntax error.
5. Type "0X" (zero followed by X). The program should reject this
line, printing a message about an invalid line number. Type "0 X".
The same thing should happen. Try "30000X", then "30000 X", and then
"3000000000 X". The program should reject these, as well.
6. Type "-1 X" and "-1X". The program should reject these lines,
printing a message either about an unrecognized command (or syntax
error), or an invalid line number.
7. Type a simple carriage return. There should be no effect, except
for any prompt being repeated.
8. Type the following exactly as shown. Note that lines 1000 and 100
each contain four spaces:
30 X
1 The
29999 Z
1000 used
100 is
10000 to test
30file --
1 This
29999 LEDIT.
9. Type "list". You should see the following, lined up exactly as
shown. There should be exactly five spaces for the line numbers.
1 This
30 file --
100 is
1000 used
10000 to test
29999 LEDIT.
-- continued --
Page 26
10. Try a line of text beginning with a number: "20000 123 45". Then
type " LIST" with three leading spaces. You should see
1 This
30 file --
100 is
1000 used
10000 to test
20000 123 45
29999 LEDIT.
11. Insert an empty line by typing "15000 ". Then type "LIST". You
should see
1 This
30 file --
100 is
1000 used
10000 to test
15000
20000 123 45
29999 LEDIT.
12. Type "EXIT ABC". LEDIT should print a error message and NOT
exit. The requirements say that the EXIT command must stand alone.
13. Type " exit". LEDIT should exit, and you should have a new
file with the output file name you gave in step 1. Type the file with
the TYPE command. You should see exactly this, starting in column 1:
This
file --
is
used
to test
123 45
LEDIT.
14. Run LEDIT again, using for an input file the name of the OUTPUT
file you specified in step 1. This time the program should say "File
found." Choose yet another name for an output file for this step.
Type "list". You should see the following, exactly as shown:
10 This
20 file --
30 is
40 used
50 to test
60
70 123 45
80 LEDIT.
-- continued --
Page 27
15. Type " LIST 30". You should see only line 30. Type
"list25-45". You should see only lines 30 and 40. Type "LIST - 40".
You should see lines 10 through 40. Type "list35 -". You should see
lines 40 through 80. Type "list 15". The program should either do
nothing or print a message that line 15 doesn't exist. Now type
"list" again and check that the result is the same as in step 14.
16. Try each of the following. In each case, LEDIT should print an
error message:
LIST -
list 2A
list 30 - 50 -
list 30 - -50
list 30-A
LIST XYZ
17. Type "70" to delete line 70. Type "LIST". You should see
10 This
20 file --
30 is
40 used
50 to test
60
80 LEDIT.
18. Delete line 60. Do not list. Now delete line 80 and list. You
should see
10 This
20 file --
30 is
40 used
50 to test
19. Delete line 10 and list. You should see lines 20 through 50
above. Delete line 50 and list. You should see lines 20 through 40.
Delete line 30 and list. You should see lines 20 and 40. Delete line
40 and list. You should see only line 20. Delete line 20 and list.
The result should be the same as in step 2. Type "EXIT".
20. If your program passed all these tests, sincere congratulations!
You've completed a difficult assignment. We hope that you feel
comfortable with Ada now. If you like, you can compare your solution
with ours, starting on page 28 of these notes. When you go back to
ADA-TUTR, you'll learn to write your own generic packages, procedures,
and functions.
Page 28
LEDIT.ANS
---------
-- Our solution to Outside Assignment 5
with TEXT_IO; use TEXT_IO;
procedure LEDIT is
MAX_LENGTH : constant := 80;
MAX_LINE_NUMBER : constant := 29_999;
type TEXT is
record
LEN : INTEGER range 0 .. MAX_LENGTH := 0;
VAL : STRING(1 .. MAX_LENGTH);
end record;
type LINK;
type P is access LINK;
type LINK is
record
NUM : POSITIVE;
LINE : TEXT;
NEXT : P;
end record;
HEAD : P := new LINK;
TEMP : P;
INPUT_FILE, OUTPUT_FILE : FILE_TYPE;
INPUT : TEXT;
FINISHED : BOOLEAN := FALSE;
LINE_NUM : NATURAL := 10;
function STR(T : in TEXT) return STRING is separate;
procedure READ_INPUT_FILE is separate;
procedure DO_COMMAND is separate;
begin
PUT("Input file: "); GET_LINE(INPUT.VAL, INPUT.LEN);
READ_INPUT_FILE;
PUT("Output file: "); GET_LINE(INPUT.VAL, INPUT.LEN);
CREATE(OUTPUT_FILE, NAME => STR(INPUT));
-- Get and process commands.
while not FINISHED loop
PUT("> "); GET_LINE(INPUT.VAL, INPUT.LEN);
DO_COMMAND;
end loop;
-- Write the output file.
TEMP := HEAD.NEXT; -- Skip unused link at start of linked list.
while TEMP /= null loop
PUT_LINE(OUTPUT_FILE, STR(TEMP.LINE)); -- Write line of text.
TEMP := TEMP.NEXT; -- Get next link.
end loop;
end LEDIT;
-- continued --
Page 29
separate(LEDIT)
function STR(T : in TEXT) return STRING is
begin
return T.VAL(1 .. T.LEN);
end STR;
separate (LEDIT)
procedure READ_INPUT_FILE is
begin -- If the input file exists, print a message and read it in.
OPEN(INPUT_FILE, IN_FILE, STR(INPUT));
PUT_LINE("File found.");
TEMP := HEAD;
while not END_OF_FILE(INPUT_FILE) loop
GET_LINE(INPUT_FILE, INPUT.VAL, INPUT.LEN); -- Read a line.
TEMP.NEXT := new LINK'(LINE_NUM, INPUT, null); -- Add to list.
TEMP := TEMP.NEXT; -- Advance pointer to next link.
LINE_NUM := LINE_NUM + 10;
end loop;
CLOSE(INPUT_FILE);
exception -- If the input file doesn't exist, just print a message.
when NAME_ERROR => PUT_LINE("File not found.");
end READ_INPUT_FILE;
separate(LEDIT)
procedure DO_COMMAND is
procedure DELETE_FIRST_CHARACTER(T : in out TEXT) is separate;
procedure GET_LEADING_INTEGER(N : out NATURAL) is separate;
procedure STRIP_LEADING_SPACES_FROM_INPUT is separate;
procedure ADD_DELETE_REPLACE_LINE is separate;
procedure LIST is separate;
begin
STRIP_LEADING_SPACES_FROM_INPUT;
if STR(INPUT) = "exit" or STR(INPUT) = "EXIT" then
FINISHED := TRUE;
elsif INPUT.LEN >= 4 and (INPUT.VAL(1 .. 4) = "list" or
INPUT.VAL(1 .. 4) = "LIST") then
LIST;
elsif INPUT.LEN > 0 and INPUT.VAL(1) not in '0' .. '9' then
PUT_LINE("Unrecognized command.");
elsif INPUT.LEN > 0 then
GET_LEADING_INTEGER(LINE_NUM);
if LINE_NUM not in 1 .. MAX_LINE_NUMBER then
PUT_LINE("Illegal line number.");
else
ADD_DELETE_REPLACE_LINE;
end if;
end if;
exception
when NUMERIC_ERROR => PUT_LINE("Line number too large.");
end DO_COMMAND;
-- continued --
Page 30
separate(LEDIT.DO_COMMAND)
procedure ADD_DELETE_REPLACE_LINE is
INP : TEXT := INPUT;
begin
if INP.LEN > 0 and INP.VAL(1) = ' ' then -- Treat "9x" like "9 x".
DELETE_FIRST_CHARACTER(INP);
end if;
TEMP := HEAD; -- Find where this number belongs in linked list.
while TEMP /= null and then TEMP.NEXT /= null and then
TEMP.NEXT.NUM <= LINE_NUM loop
if TEMP.NEXT.NUM = LINE_NUM then
TEMP.NEXT := TEMP.NEXT.NEXT; -- Delete line.
else
TEMP := TEMP.NEXT; -- Advance to next link in list.
end if;
end loop;
if INPUT.LEN > 0 then -- Add line.
TEMP.NEXT := new LINK'(LINE_NUM, INP, TEMP.NEXT);
end if;
end ADD_DELETE_REPLACE_LINE;
separate(LEDIT.DO_COMMAND)
procedure DELETE_FIRST_CHARACTER(T : in out TEXT) is
begin
T.VAL(1 .. MAX_LENGTH - 1) := T.VAL(2 .. MAX_LENGTH);
T.LEN := T.LEN - 1;
end DELETE_FIRST_CHARACTER;
separate(LEDIT.DO_COMMAND)
procedure GET_LEADING_INTEGER(N : out NATURAL) is
ANS: INTEGER := 0;
begin
while INPUT.LEN > 0 and INPUT.VAL(1) in '0' .. '9' loop
ANS := ANS*10 + CHARACTER'POS(INPUT.VAL(1)) -CHARACTER'POS('0');
DELETE_FIRST_CHARACTER(INPUT);
end loop;
N := ANS;
end GET_LEADING_INTEGER;
separate(LEDIT.DO_COMMAND)
procedure STRIP_LEADING_SPACES_FROM_INPUT is
begin
while INPUT.LEN > 0 and INPUT.VAL(1) = ' ' loop
DELETE_FIRST_CHARACTER(INPUT);
end loop;
end STRIP_LEADING_SPACES_FROM_INPUT;
-- continued --
Page 31
separate(LEDIT.DO_COMMAND)
procedure LIST is
package IIO is new INTEGER_IO(INTEGER); use IIO;
START, FINISH : NATURAL;
VALID : BOOLEAN := TRUE;
begin
INPUT.LEN := INPUT.LEN - 4; -- Delete the name of the command.
INPUT.VAL(1 .. MAX_LENGTH - 4) := INPUT.VAL(5 .. MAX_LENGTH);
STRIP_LEADING_SPACES_FROM_INPUT;
if INPUT.LEN = 0 then -- For "LIST" alone, list all lines.
START := 0;
FINISH := MAX_LINE_NUMBER + 1;
else
GET_LEADING_INTEGER(START); -- Get number after "LIST".
STRIP_LEADING_SPACES_FROM_INPUT;
if INPUT.LEN = 0 then -- For "LIST n", list only line n.
FINISH := START;
elsif INPUT.VAL(1) /= '-' then -- Else "-" must follow n.
VALID := FALSE;
else
DELETE_FIRST_CHARACTER(INPUT); -- Delete the "-".
STRIP_LEADING_SPACES_FROM_INPUT;
GET_LEADING_INTEGER(FINISH); -- Get number after "-".
STRIP_LEADING_SPACES_FROM_INPUT;
if FINISH = 0 and START = 0 then -- "LIST -" isn't valid.
VALID := FALSE;
elsif FINISH = 0 then -- For "LIST n -", list n through end.
FINISH := MAX_LINE_NUMBER + 1;
end if;
VALID := VALID and INPUT.LEN = 0; -- No trailing garbage.
end if;
end if;
if not VALID then
PUT_LINE("Illegal syntax for LIST.");
else
TEMP := HEAD.NEXT; -- Skip unused link at start of linked list.
while TEMP /= null and then TEMP.NUM <= FINISH loop
if TEMP.NUM >= START then
PUT(TEMP.NUM, WIDTH => 5); -- Print line number, width 5.
PUT_LINE(' ' & STR(TEMP.LINE)); -- Print text of line.
end if;
TEMP := TEMP.NEXT; -- Get next link.
end loop;
end if;
exception
when NUMERIC_ERROR => PUT_LINE("Line number too large in LIST.");
end LIST;
Page 32
TASKING.DUM
-----------
with text_io, calendar; use text_io, calendar;
procedure tasking is
interval : constant duration := 5.0;
total_intervals : constant positive := 9;
start_time : constant time := clock;
quitting_time : constant time := start_time +
total_intervals*interval;
next_time : time := start_time;
task type tick is
entry make_noise;
entry shutdown;
end tick;
t : tick;
task body tick is
quit : boolean := false;
begin
while not quit loop
select
accept make_noise do
put_line("Tick!");
end make_noise;
or
accept shutdown;
quit := true;
end select;
end loop;
end tick;
begin
while next_time < quitting_time loop
t.make_noise;
next_time := next_time + interval;
delay next_time - clock; new_line;
end loop;
t.shutdown;
end tasking;
Page 33
STEPS FOR OUTSIDE ASSIGNMENT 6, EXERCISE IN TASKING
1. Make a copy of TASKING.DUM by typing COPY TASKING.DUM TASKING.ADA.
Compile, link, and execute the program to make sure it prints
"Tick!" nine times.
2. Edit TASKING.ADA to become your solution. Make your changes in
upper case.
3. Compile TASKING.ADA, link, and execute.
4. Compare your output with page 34 of these notes. If there are any
errors, go back to step 2.
5. When your output agrees with these notes, you've finished the
assignment and will have a chance to compare your solution with
ours.
Page 34
OUTPUT FROM TASKING.EXE AFTER MODIFICATION OF TASKING.ADA
C>tasking
Task number 1 is starting.
Task number 2 is starting.
Task number 3 is starting.
Task number 1 is starting.
Task number 2 is starting.
Task number 1 is starting.
Task number 3 is starting.
Task number 1 is starting.
Task number 2 is starting.
Task number 1 is starting.
Task number 3 is starting.
C>
Page 35
TASKING.ANS
-----------
-- Our solution to Outside Assignment 6
with text_io, calendar; use text_io, calendar;
procedure tasking is
interval : constant duration := 5.0;
total_intervals : constant positive := 9;
start_time : constant time := clock;
quitting_time : constant time := start_time +
total_intervals*interval;
next_time : time := start_time;
task type tick is
ENTRY IDENTIFY(TASK_NUMBER : IN NATURAL);
entry shutdown;
end tick;
T : ARRAY(1 .. 3) OF TICK;
PERIOD : CONSTANT ARRAY(T'RANGE) OF POSITIVE := (2, 3, 4);
TIMER : ARRAY(T'RANGE) OF NATURAL := (OTHERS => 0);
task body tick is
quit : boolean := false;
begin
while not quit loop
select
ACCEPT IDENTIFY(TASK_NUMBER : IN NATURAL) DO
PUT_LINE("Task number" & INTEGER'IMAGE(TASK_NUMBER) &
" is starting.");
END IDENTIFY;
or
accept shutdown;
quit := true;
end select;
end loop;
end tick;
begin
while next_time < quitting_time loop
FOR I IN T'RANGE LOOP
IF TIMER(I) = 0 THEN
T(I).IDENTIFY(I);
TIMER(I) := PERIOD(I);
END IF;
TIMER(I) := TIMER(I) - 1;
END LOOP;
next_time := next_time + interval;
delay next_time - clock; new_line;
end loop;
FOR I IN T'RANGE LOOP
T(I).SHUTDOWN;
END LOOP;
end tasking;
Page 36
DISCLAIMER OF WARRANTY
We hate legal mumbo jumbo, but we have to say the following to protect
ourselves:
Software Innovations Technology makes no warranty of any kind,
expressed or implied, including any warranties of merchantability or
fitness for a particular purpose. We shall not be liable for any
damages, whether direct, indirect, incidental, special, or
consequential, arising from a failure of this program to operate in a
manner desired by the user. We shall not be liable for any damage to
data or property which may be caused directly or indirectly by use of
this program. IN NO EVENT SHALL SOFTWARE INNOVATIONS TECHNOLOGY BE
LIABLE FOR ANY DAMAGES, INCLUDING ANY LOST PROFITS, LOST SAVINGS, OR
OTHER INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
INABILITY TO USE THIS PROGRAM, OR FOR ANY CLAIM BY ANY OTHER PARTY.